const { getSearchList, login, download, onlineAddBook, getTempBid, getKey, deleteMyBooks } = require('./service')
const bookS = require('../../service/book')
const bookU = require('../../util/book')
const axios = require('./request')
const path = require('path')
const fs = require('fs')
const log4js = require('../../config/log4js')
const log = log4js.getLogger('schedule')
const error = log4js.getLogger('error')
const { Book } = require('../../db')
const config = require('../../config/config')

const account = {
  email: '',
  uid: '',
  password: ''
}

/**
 * 初始化书源
 */
async function initBS () {
  account.email = config.getConf('bookSource:epubee:email')
  account.uid = `${config.getConf('bookSource:epubee:uid')}`
  account.password = config.getConf('bookSource:epubee:password')
  await attachCookie()
  // console.log(account)
}

async function attachCookie () {
  const Cookie = await login(account.uid, account.email, account.password)
  account.Cookie = Cookie
  log.info(`epubee's Cookie is: ${Cookie}`)
  axios.interceptors.request.use(config => {
    config['headers'].Cookie = account.Cookie
    return config
  })
}

/**
 * 检查书源状态
 * 若无异常，则本方法正常执行完毕即可
 * 若有异常，直接抛出异常由上层调用者捕获处理
 */
async function checkBSStatus () {}

/**
 * 搜书接口
 * @param {options} 按照searchOptions中的定义传参
 */
async function searchBook (options) {
  if (options && options.name) {
    const res = await getSearchList(options.name)
    const books = res.data.d
    if (books) {
      books.forEach(book => {
        book.bname = book.Title
        book.bid = book.BID
        book.author = book.Author
      })
    }
    return books
  } else {
    throw new Error('参数错误')
  }
}

/**
 * 下载之前的准备
 * @param {object} options 传回在searchBook中返回的所有书籍信息
 * @returns {boolean} 返回操作是否成功
 */
async function preDownload (options) {
  const res = await onlineAddBook(options.bid, account.uid)
  if (res.data['d'] && res.data['d'].length) {
    error.error(res)
    throw new Error('保存书籍到epubee失败，请查看详细错误日志')
  } else {
    return options
  }
}

/**
 * 下载书籍
 * @param {object} options 传回在preDownload中返回的所有书籍信息
 */
async function downloadBook (options) {
  const { name, postfix } = bookU.transferBookTitleToNameAndPostfix(options.bname)
  const bid = await getTempBid(account.uid, name, options.author)
  const res = await getKey(account.uid, bid)
  const key = res.data['d'][0]
  if (!key || key.length < 12) {
    error.error(key)
    throw new Error('获取下载书籍的Key失败')
  }
  const res2 = await download(bid, account.uid, key)
  const d = new Date()
  const savePath = path.join(
    bookS.ensureFilePath(`book/src/${d.getFullYear()}/${d.getMonth()}`),
    `${bookU.resolveTooLongBookName2(name)}${postfix}`
  )
  fs.writeFileSync(savePath, res2.data)
  const { distPath, size } = bookS.transferSrcBookToDist(savePath)
  if (size < 1024) {
    throw new Error(`book size: ${size}, 因书籍大小小于1kb判断书籍下载失败！`)
  }
  const savedBook = await Book.findByIdAndUpdate(options.bookId, {
    size,
    uri: distPath
  })

  log.info(`savedBook is: ${savedBook}`)

  options.tempBid = bid
  return options
}

/**
 * 下载之后处理一些后续事情
 * @param {object} options 传回在downloadBook中返回的所有书籍信息
 */
async function postDownload (options) {
  await deleteMyBooks(account.uid, `0,${options.tempBid}`)
}

module.exports = {
  name: 'epubee',
  searchOptions: {
    conditions: [
      {
        name: 'name', // 不要以BS开头
        UIName: '书名或作者名'
      }
    ]
  },
  initBS,
  searchBook,
  checkBSStatus,
  attachCookie,
  saveBook: false,
  preDownload,
  downloadBook,
  postDownload
}
